package se.webbzon.boltzmann.object.factory;

import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;

import se.webbzon.boltzmann.environment.AbstractEnvironment;
import se.webbzon.oschi01.worldeditor.WorldMovableObjectDeflation;
import se.webbzon.oschi01.worldobject.WorldMovableObject;
import se.webbzon.oschi01.worldobject.WorldObject;
import se.webbzon.oschi01.worldobject.WorldStaticObject;

public class InstanceFactoryDeflation extends WorldMovableObjectDeflation {
	
	// The name of the instance factory
	private String factoryName;

	/*============================================================
	Constructors
	============================================================*/
	
	public InstanceFactoryDeflation(int deflationProperties, InstanceFactoryObject factoryObject) {
		super(deflationProperties,null,factoryObject);
		factoryName = factoryObject.getFactoryName();
	}
	
	public InstanceFactoryDeflation(int deflationProperties) {
		super(deflationProperties,null);
	}
	
	/*============================================================
	Public Methods
	============================================================*/
	
	public WorldObject makeWorldObject(	AbstractEnvironment env, 
										InstanceFactoryGroup factories) 
												throws InstanceFactoryException {
		// Return the factory object is game mode is turned off
		WorldObject instance;
		if (!env.isDebugMode() || factoryName.isEmpty())
			instance = new InstanceFactoryObject(factoryName);
		else {
			// Find the factory
			InstanceFactory factory = factories.getFactory(factoryName);
			if (factory == null)
				throw new InstanceFactoryException("No factory was found with the name \"" + 
											factoryName + "\".");
			instance = factory.makeNew(env);
		}
		
		// Initialize the instance
		if (instance instanceof WorldStaticObject) {
			WorldStaticObject wso;
			if (instance instanceof WorldMovableObject) {
				WorldMovableObject wmo = (WorldMovableObject) instance;
				wmo.setVelocity(getXVelocity(), getYVelocity(), getZVelocity());
				wmo.setAcceleration(getXAcceleration(), 
									getYAcceleration(), 
									getZAcceleration());
				wso = wmo;
			} else
				wso = (WorldStaticObject) instance;
			wso.setPosition(getX(), getY(), getZ());
			wso.setSize(getWidth(), getHeight(), getDepth());
			wso.setRotation(getEX(), getEY(), getEZ(), getAngle());
			wso.setVisible(isVisible());
			wso.setSolid(isSolid());
		}
					
		return instance;
	}

	@Override public void inflate(ByteBuffer buff) {
		super.inflate(buff);
		byte[] factoryNameData = new byte[buff.getShort()];
		buff.get(factoryNameData, 0, factoryNameData.length);
		try {
			factoryName = new String(factoryNameData,"UTF-8");
		} catch (UnsupportedEncodingException e) {
			factoryName = "";
		}
	}

	@Override public ByteBuffer deflate(int allocate) {
		byte[] factoryNameData;
		try {
			factoryNameData = factoryName.getBytes("UTF-8");
		} catch (UnsupportedEncodingException e) {
			factoryNameData = new byte[0];
		}
		ByteBuffer buff = super.deflate(factoryNameData.length + 2);
		buff.putShort((short) factoryNameData.length);
		buff.put(factoryNameData);
		return buff;
	}

}
